package com.salary.utils.reader;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

public abstract class DataReader<T> {
    private static final Logger logger = LoggerFactory.getLogger(DataReader.class);
    // 公共逻辑：校验文件是否存在
    protected void validateFile(String filePath) throws IOException {
//        File file = new File(path);
//        if (!file.exists()) throw new IOException("File not found: " + path);
    }

    // 抽象方法：子类实现具体解析逻辑
    public abstract T readData(String filePath);

    // 钩子方法（可选）：预处理内容
    protected String preprocess(String content) {
        return content;
    }

    /**
     * 获取单元格的字符串值
     */
    public static String getCellValueAsString(Cell cell) {
        if (cell == null) return "";

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 对于日期类型，返回Date对象的toString格式
                    return cell.getDateCellValue().toString();
                } else {
                    // 对于数值，尝试保留原始格式
                    double numValue = cell.getNumericCellValue();
                    // 检查是否为整数
                    if (numValue == Math.floor(numValue)) {
                        return String.valueOf((long) numValue);
                    } else {
                        return String.valueOf(numValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    // 首先尝试获取公式计算结果的字符串值
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    try {
                        // 如果是数值结果
                        double numValue = cell.getNumericCellValue();
                        if (DateUtil.isCellDateFormatted(cell)) {
                            // 如果公式结果是日期
                            return cell.getDateCellValue().toString();
                        } else if (numValue == Math.floor(numValue)) {
                            // 如果是整数
                            return String.valueOf((long) numValue);
                        } else {
                            return String.valueOf(numValue);
                        }
                    } catch (Exception ex) {
                        // 如果无法获取计算结果，返回公式本身
                        return cell.getCellFormula();
                    }
                }
            default:
                return "";
        }
    }
    /**
     * 获取单元格的数值
     */
    public static double getCellValueAsDouble(Cell cell) {
        if (cell == null) return 0;

        switch (cell.getCellType()) {
            case NUMERIC:
                return cell.getNumericCellValue();
            case STRING:
                try {
                    return Double.parseDouble(cell.getStringCellValue());
                } catch (NumberFormatException e) {
                    return 0;
                }
            case BOOLEAN:
                return cell.getBooleanCellValue() ? 1 : 0;
            case FORMULA:
                try {
                    return cell.getNumericCellValue();
                } catch (Exception e) {
                    return 0;
                }
            default:
                return 0;
        }
    }

    /**
     * 通用方法：根据列名在表头行中查找列索引
     *
     * @param sheet Excel工作表
     * @param columnNames 要查找的列名数组，支持模糊匹配
     * @return 列名到索引的映射，未找到的列名不会包含在返回结果中
     */
    public static Map<String, Integer> findColumnIndices(Sheet sheet, String[] columnNames) {
        Map<String, Integer> columnIndices = new HashMap<>();
        if (sheet == null) return columnIndices;

        // 创建列名到可能匹配文本的映射
        Map<String, List<String>> columnMatchers = new HashMap<>();
        for (String columnName : columnNames) {
            List<String> matchers = new ArrayList<>();
            matchers.add(columnName); // 精确匹配
            columnMatchers.put(columnName, matchers);
        }

        // 记录列查找的初始状态
        logger.info("开始查找列，要查找的列: " + Arrays.toString(columnNames));

        // 检查前5行，查找列标题
        for (int rowIndex = 0; rowIndex <= 3; rowIndex++) {
            Row headerRow = sheet.getRow(rowIndex);
            if (headerRow == null) continue;

            // 遍历所有列，查找匹配的列名
            for (int colIndex = 0; colIndex < headerRow.getLastCellNum(); colIndex++) {
                Cell cell = headerRow.getCell(colIndex);
                if (cell == null) continue;

                String cellValue = getCellValueAsString(cell).trim();
                if (cellValue.isEmpty()) continue;

                // 对每个要查找的列名进行匹配
                for (String columnName : columnNames) {
                    // 如果该列名已经找到，跳过
                    if (columnIndices.containsKey(columnName)) {
                        continue;
                    }

                    List<String> matchers = columnMatchers.get(columnName);

                    // 检查是否匹配任一条件
                    boolean matched = false;
                    String matchedPattern = null;
                    for (String matcher : matchers) {
                        if (cellValue.equals(matcher) || cellValue.contains(matcher)) {
                            matched = true;
                            matchedPattern = matcher;
                            break;
                        }
                    }

                    // 如果匹配成功，记录索引
                    if (matched) {
                        columnIndices.put(columnName, colIndex);
                        logger.info("在第" + (rowIndex+1) + "行第" + (colIndex+1) + "列找到" + columnName +
                                "列，单元格值: '" + cellValue + "'，匹配模式: '" + matchedPattern + "'");
                        break; // 找到匹配后不再为其他列名检查该单元格
                    }
                }
            }
        }

        // 输出最终找到的所有列
        for (Map.Entry<String, Integer> entry : columnIndices.entrySet()) {
            logger.info("最终确定：" + entry.getKey() + " 列在索引: " + entry.getValue() + " (第" + (entry.getValue()+1) + "列)");
        }

        return columnIndices;
    }


}
